﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Drawing;

namespace PhotoOfTheDay.Types
{
    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct Photo
    {
        fixed byte photoName[255];
        
        public string PhotoName
        {
            get
            {
                char[] ch = new char[255];
                fixed (char* c = ch)
                {
                    fixed (byte* b = photoName)
                    {
                        Encoding.Unicode.GetChars(b, 255, c, 255);
                    }
                }
                string s = new string(ch);
                if (s.IndexOf("\0") >= 0)
                    s = s.Substring(0, s.IndexOf("\0"));
                return s;
            }
            set
            {
                string s = value;
                if (s.IndexOf("\0") >= 0)
                    s = s.Substring(0, s.IndexOf("\0"));
                fixed (char* c = s)
                {
                    fixed (byte* b = photoName)
                    {
                        Encoding.Unicode.GetBytes(c, s.Length, b, 255);
                    }
                }
            }
        }

        fixed byte  photoURL[2048];

        public string PhotoURL
        {
            get
            {
                char[] ch = new char[2048];
                fixed (char* c = ch)
                {
                    fixed (byte* b = photoURL)
                    {
                        Encoding.Unicode.GetChars(b, 2048, c, 2048);
                    }
                }
                string s = new string(ch);
                if (s.IndexOf("\0") >= 0)
                    s = s.Substring(0, s.IndexOf("\0"));
                return s;
            }
            set
            {
                string s = value;
                if (s.IndexOf("\0") >= 0)
                    s = s.Substring(0, s.IndexOf("\0"));
                fixed (char* c = s)
                {
                    fixed (byte* b = photoURL)
                    {
                        Encoding.Unicode.GetBytes(c, s.Length, b, 2048);
                    }
                }
            }
        }

        public DateTime photoDate;
        public bool PreviousAvailable;
        fixed byte previousLink[2048];

        public string PreviousLink
        {
            get
            {
                char[] ch = new char[2048];
                fixed (char* c = ch)
                {
                    fixed (byte* b = previousLink)
                    {
                        Encoding.Unicode.GetChars(b, 2048, c, 2048);
                    }
                }
                string s = new string(ch);
                if (s.IndexOf("\0") >= 0)
                    s = s.Substring(0, s.IndexOf("\0"));
                return s;
            }
            set
            {
                string s = value;
                if (s.IndexOf("\0") >= 0)
                    s = s.Substring(0, s.IndexOf("\0"));
                fixed (char* c = s)
                {
                    fixed (byte* b = previousLink)
                    {
                        Encoding.Unicode.GetBytes(c, s.Length, b, 2048);
                    }
                }
            }
        }

        public bool NextAvailable;
        fixed byte nextLink[2048];

        public string NextLink
        {
            get
            {
                char[] ch = new char[2048];
                fixed (char* c = ch)
                {
                    fixed (byte* b = nextLink)
                    {
                        Encoding.Unicode.GetChars(b, 2048, c, 2048);
                    }
                }
                string s = new string(ch);
                if (s.IndexOf("\0") >= 0)
                    s = s.Substring(0, s.IndexOf("\0"));
                return s;
            }
            set
            {
                string s = value;
                if (s.IndexOf("\0") >= 0)
                    s = s.Substring(0, s.IndexOf("\0"));
                fixed (char* c = s)
                {
                    fixed (byte* b = nextLink)
                    {
                        Encoding.Unicode.GetBytes(c, s.Length, b, 2048);
                    }
                }
            }
        }

        public static Photo Navigate(string URL, bool AddToArchive)
        {
            Global.IsCopyrighted = false;
            Photo p = default(Photo);
            p.PhotoURL = URL;
            string raw = Global.GetHTTPData(URL);
            string TempData = raw;

            //Internet problem, link could not be loaded
            if (raw == "") return default(Photo);

            int success = 0;

            //First get the image url
            if (raw.IndexOf("<div class=\"download_link\">") < 0)
            {
               //not permitted to use
                Global.PhotoFound = false;
                Global.CurrentImage = null;
            }
            else
            {
                raw = Scraper.GetInnerData(raw, "<div class=\"download_link\">", "</div>");
                raw = Scraper.GetAnchorURL(raw);
                Global.PhotoFound = true;
                if (raw.StartsWith("//")) raw = "http:" + raw;
                //Load the bitmap too
                System.IO.Stream s = new System.Net.WebClient().OpenRead(raw);
                Global.CurrentImage = (Bitmap)Bitmap.FromStream(s);
                success++;
            }

            //get the navigation urls
            raw = TempData;
            raw = Scraper.GetInnerData(raw, "<div class=\"nav\">", "</div>");
            raw = raw.Trim();

            string NavData = raw;
            //get previous
            raw = Scraper.GetInnerDataRev(raw, "Previous", "<a href=\"");
            raw = Scraper.GetAnchorURL(raw);
            if (raw == "")
            {
                p.PreviousAvailable = false;
            }
            else
            {
                p.PreviousAvailable = true;
                p.PreviousLink = Global.BaseURL + raw;
                success++;
            }
            //get next
            raw = NavData;
            raw = Scraper.GetInnerDataRev(raw, "Next", "<a href=\"");
            raw = Scraper.GetAnchorURL(raw);
            if (raw == "")
            {
                p.NextAvailable = false;
            }
            else
            {
                p.NextAvailable = true;
                p.NextLink = Global.BaseURL + raw;
                success++;
            }

            if (success < 1) return default(Photo); //if none is true then error with internet connection

            //Codes below has been commented out as it is a violation of copyright to download
            //photoes that has not been intended for downloading
            //one option can be, load them but don't let people download
            if (!Global.PhotoFound)
            {
                //Load the low res photo
                raw = TempData;
                raw = Scraper.GetInnerData(raw, "<div class=\"primary_photo\">", "</div>");
                raw = Scraper.GetInnerData(raw, "<img src=\"", "\"");
                //low res image found
                Global.PhotoFound = true;
                if (raw.StartsWith("//")) raw = "http:" + raw;
                //Load the bitmap too
                try
                {
                    System.IO.Stream s = new System.Net.WebClient().OpenRead(raw);
                    Global.CurrentImage = (Bitmap)Bitmap.FromStream(s);
                }
                catch
                {
                    return default(Photo);
                }
                //copyrighted image, handle carefully
                //Global.IsCopyrighted = true;
            }

            //get caption and publication date
            raw = TempData;
            raw = Scraper.GetInnerData(raw, "<div id=\"caption\">", "</div>");

            string pubdate = Scraper.GetInnerData(raw, "<p class=\"publication_time\">", "</p>");
            string caption = Scraper.GetInnerData(raw, "<h2>", "</h2>");
            p.PhotoName = caption;
            p.photoDate = DateTime.Parse(pubdate);

            //If archive on please save the image in archive
            if (AddToArchive && (!Global.IsCopyrighted))
            {
                string mypicture = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyPictures);
                mypicture = Path.Combine(mypicture, "Photo of the Day");
                if (!Directory.Exists(mypicture))
                {
                    Directory.CreateDirectory(mypicture);
                }
                mypicture = Path.Combine(mypicture, pubdate + " - " + caption + ".bmp");
                if (Global.PhotoFound)
                {
                    Global.CurrentImage.Save(mypicture, System.Drawing.Imaging.ImageFormat.Bmp);
                }
            }

            return p;
        }

    }
}
